#include <stdio.h>  // for printf
#include <unistd.h>  // for sleep
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_uart.h"
#include "WifiSta.h"
#include "MQTTClient.h"
#include "cJSON.h"
#define SSID "Nice"
#define KEY "12312312"
#define HOST_ADDR "baaeb697c9.st1.iotda-device.cn-north-4.myhuaweicloud.com"
#define SERVICE_ID "Agriculture"
#define DEVICE_ID "668c8ea85830dc113ecb9728_music_iot_0_0_2024071107"
#define DEVICE_USER "668c8ea85830dc113ecb9728_music_iot"
#define DEVICE_PWD "a9357a5d6502bdc6ebe197bada5450c91888d36dfce08bf82f526beaa2f7270c"
#define TOPIC_PUBLISH "$oc/devices/"DEVICE_ID"/sys/properties/report"
#define TPOIC_SUBCRIB "$oc/devices/"DEVICE_USER"/sys/commands/#"
#define TOPIC_RESPONSE "$oc/devices/"DEVICE_USER"/sys/commands/response/"
#define KEY2_IO_GPIO_02 2
#define KEY3_IO_GPIO_07 7
#define KEY4_IO_GPIO_09 9
#define KEY5_IO_GPIO_08 8
#define WIFI_IOT_UART_IDX_1 1
unsigned char  cmdPlay[]={0xfd,0x02,0x01,0xdf};
unsigned char  cmdStop[]={0xfd,0x02,0x0e,0xdf};
unsigned char  cmdPrev[]={0xfd,0x02,0x04,0xdf};
unsigned char  cmdNext[]={0xfd,0x02,0x03,0xdf};
MQTTClient client;
Network network;
int music = 2,pmusic = 2,flag;
static unsigned char sendBuf[1000];
static unsigned char recvBuf[1000];

static void MusicTask(void);
static void TASK2(void);
static void TASK3(void);
static void Key2Pressed(char *arg);
static void Key3Pressed(char *arg);
static void Key4Pressed(char *arg);
static void Key5Pressed(char *arg);
void messageHandle(MessageData *data);
void message_Cmdback(char *data);

static void MusicModuleSample(void)
{

    osThreadAttr_t attr;

    attr.name = "MusicTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 1024 * 10;
    attr.priority = osPriorityNormal;
    osThreadNew((osThreadFunc_t)MusicTask, NULL, &attr);
    attr.name = "TASK2";
    osThreadNew((osThreadFunc_t)TASK2, NULL, &attr);
    attr.name = "TASK3";
    osThreadNew(TASK3,NULL,&attr);
}
void TASK2(){
    WifiConnect(SSID,KEY);   
    NetworkInit(&network);
    printf("NetworkInit\n");
begin:    
    NetworkConnect(&network,HOST_ADDR,1883);
    printf("MqttClinetInit\n");
    MQTTClientInit(&client,&network,2000,sendBuf,sizeof(sendBuf),recvBuf,sizeof(recvBuf));
    //配置平台端MQTT连接
    MQTTString clientId = MQTTString_initializer;
    clientId.cstring = DEVICE_ID;
    MQTTString clientUser = MQTTString_initializer;
    clientUser.cstring = DEVICE_USER;
    MQTTString clientPwd = MQTTString_initializer;
    clientPwd.cstring = DEVICE_PWD;
    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    data.clientID = clientId;
    data.username = clientUser;
    data.password = clientPwd;
    data.willFlag = 0;
    data.MQTTVersion = 4;
    data.keepAliveInterval = 60;
    data.cleansession = 1;
    printf("MQTTConect\n");
    int rc = MQTTConnect(&client,&data);
    if(rc != 0){
        printf("MQTTConect %d\n",rc);
        NetworkDisconnect(&network);
        MQTTDisconnect(&client);
        sleep(2);
        goto begin;
    }
    //配置订阅指令
    printf("MQTTSUBCRIBE\n");
    rc = MQTTSubscribe(&client,TPOIC_SUBCRIB,0,messageHandle);
    if(rc != 0){
        printf("MQTTSubscribe %d\n",rc);
        NetworkDisconnect(&network);
        MQTTDisconnect(&client);
        sleep(2);
        goto begin;
    }

    // while(1){
    //     MQTTMessage message;
    //     char payload[100] = {0};
    //     cJSON *root = cJSON_CreateObject();
    //     if(root != NULL){
    //         cJSON *serv_arr = cJSON_AddArrayToObject(root,"services");
    //         cJSON *arr_item = cJSON_CreateObject();
    //         cJSON_AddStringToObject(arr_item,"service_id",SERVICE_ID);
    //         cJSON *pro_obj = cJSON_CreateObject();
    //         cJSON_AddItemToObject(arr_item,"properties",pro_obj);

    //         // if(led_on == 1) cJSON_AddStringToObject(pro_obj,"Light","ON");
    //         // else if(led_on == 0)  cJSON_AddStringToObject(pro_obj,"Light","OFF");
    //         // cJSON_AddNumberToObject(pro_obj,"Smoke",smoke_adc);

    //         cJSON_AddItemToArray(serv_arr,arr_item);
    //         char *play_str = cJSON_PrintUnformatted(root);
    //         strcpy(payload,play_str);
    //         cJSON_free(play_str);
    //         cJSON_Delete(root);
    //     }
    //     message.qos = 0;
    //     message.retained = 0;
    //     message.payload = payload;
    //     message.payloadlen = strlen(payload);
    //     if((rc = MQTTPublish(&client,TOPIC_PUBLISH,&message)) != 0){
    //         printf("MQTT Publish Failed\n");
    //         NetworkDisconnect(&network);
    //         MQTTDisconnect(&client);
    //         sleep(2);
    //         goto begin;
    //     }else {
    //         printf("mqtt publish success:%s\n",payload);
    //     }
    //     MQTTYield(&client,3000);
    // }
}
void messageHandle(MessageData *data){
    //printf("messeage on topic:%s,data%s\n",data->topicName->lenstring.data,data->message->payload);
    char *request_id_idx = NULL;
    request_id_idx = strstr(data->topicName->lenstring.data,"request_id=");
    char request_id[50] = {0};
    strncpy(request_id,request_id_idx + 11,36);
    //printf("requestId = %s\n",request_id);
    cJSON *root = cJSON_ParseWithLength(data->message->payload,data->message->payloadlen);
    if(root != NULL){
        cJSON *cmd_name = cJSON_GetObjectItem(root,"command_name");
        if(cmd_name != NULL){
            char *cmd_name_str = cJSON_GetStringValue(cmd_name);
            printf("command_name :%s\n",cmd_name_str);
            if(strcmp(cmd_name_str,"Music") ==0){
                cJSON *para_obj = cJSON_GetObjectItem(root,"paras");
                cJSON *status_obj = cJSON_GetObjectItem(para_obj,"Music");
                music = (int)cJSON_GetNumberValue(status_obj);
                flag = 1;
                // if(music == 1){
                //     if()
                //     printf("111\n");
                //     }
                // else if(music == 2){
                //     printf("222\n");
                // } 
            }
        }
        message_Cmdback(request_id);
        cJSON_Delete(root);
    }
}
void TASK3(void){
    while(1){
        if(flag != 0){
            if(music != pmusic){//切歌
                pmusic = music;
                IoTUartWrite(WIFI_IOT_UART_IDX_1, (unsigned char *)cmdNext, 4);
                sleep(5);
                IoTUartWrite(WIFI_IOT_UART_IDX_1, (unsigned char *)cmdStop, 4);
            }else{//不切歌
                IoTUartWrite(WIFI_IOT_UART_IDX_1, (unsigned char *)cmdPlay, 4);
                sleep(5);
                IoTUartWrite(WIFI_IOT_UART_IDX_1, (unsigned char *)cmdStop, 4);
            }
            flag = 0;
        }
        usleep(1000);
    }
}
//指令返回
void message_Cmdback(char *data){
    char retopic_str[128] = {0};
    sprintf(retopic_str,"%srequest_id=%s",TOPIC_RESPONSE,data);
    printf("retopic = %s\n",retopic_str);
    MQTTMessage message;
    char payload[200] = {0};
    message.qos = 0;
    message.retained = 0;
    sprintf(payload,"{\
    \"result_code\": 0,\
    \"response_name\": \"COMMAND_RESPONSE\",\
    \"paras\": {\
        \"result\": \"success\"\
    }\
    }");
    message.payload = payload;
    message.payloadlen = strlen(payload);
    int rc;
    if((rc = MQTTPublish(&client,retopic_str,&message)) != 0){
        printf("MessageCmdback Publish Failed\n");
        NetworkDisconnect(&network);
        MQTTDisconnect(&client);
        sleep(2);
    }else {
        printf("MessageCmdback publish success:%s\n",payload);
    }
}
static void MusicTask(void)
{    
    /* 初始化KEY5 GPIO */
    sleep(3);
    int ret = IoTGpioInit(KEY5_IO_GPIO_08);
    if(ret != 0){ 
        printf("IoTGpioInit failed :%#x \r\n", ret);
		return;
    }

    /* 设置F5按键复用GPIO */
    ret = IoTGpioSetFunc(KEY5_IO_GPIO_08, IOT_GPIO_FUNC_GPIO_8_GPIO);
    if(ret != 0){ 
        printf("IoTGpioInit failed :%#x \r\n", ret);
		return;
    }

    /* 设置F5按键为输入控制 */
    ret = IoTGpioSetDir(KEY5_IO_GPIO_08, IOT_GPIO_DIR_IN);
    if(ret != 0){ 
        printf("IoTGpioSetDir failed :%#x \r\n", ret);
        return;
    }

    /* 设置F5按键为上拉控制 */
    ret = IoTGpioSetPull(KEY5_IO_GPIO_08, IOT_GPIO_PULL_UP);
    if(ret != 0){ 
        printf("IoTGpioSetPull failed :%#x \r\n", ret);
		return;
    }

    /* 设置F5按键为下降沿触发中断 */
    ret = IoTGpioRegisterIsrFunc(KEY5_IO_GPIO_08, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW, Key5Pressed, NULL);
    if(ret != 0){ 
        printf("IoTGpioRegisterIsrFunc failed :%#x \r\n", ret);
		return;
    }

    /* 设置F4按键复用GPIO */
    ret = IoTGpioSetFunc(KEY4_IO_GPIO_09, IOT_GPIO_FUNC_GPIO_9_GPIO);
    if(ret != 0){ 
        printf("IoTGpioInit failed :%#x \r\n", ret);
		return;
    }

    /* 设置F4按键为输入控制 */
    ret = IoTGpioSetDir(KEY4_IO_GPIO_09, IOT_GPIO_DIR_IN);
    if(ret != 0){ 
        printf("IoTGpioSetDir failed :%#x \r\n", ret);
		return;
    }

    /* 设置F4按键为上拉控制 */
    ret = IoTGpioSetPull(KEY4_IO_GPIO_09, IOT_GPIO_PULL_UP);
    if(ret != 0){ 
        printf("IoTGpioSetPull failed :%#x \r\n", ret);
		return;
    }

    /* 设置F4按键为下降沿触发中断 */
    ret = IoTGpioRegisterIsrFunc(KEY4_IO_GPIO_09, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW, Key4Pressed, NULL);
    if(ret != 0){ 
        printf("IoTGpioRegisterIsrFunc failed :%#x \r\n", ret);
        return;
    }

    /* 设置F3按键复用GPIO */
    ret = IoTGpioSetFunc(KEY3_IO_GPIO_07, IOT_GPIO_FUNC_GPIO_7_GPIO);
    if(ret != 0){ 
        printf("IoTGpioInit failed :%#x \r\n", ret);
		return;
    }

    /* 设置F3按键为输入控制 */
    ret = IoTGpioSetDir(KEY3_IO_GPIO_07, IOT_GPIO_DIR_IN);
    if(ret != 0){ 
        printf("IoTGpioSetDir failed :%#x \r\n", ret);
		return;
    }

    /* 设置F3按键为上拉控制 */
    ret = IoTGpioSetPull(KEY3_IO_GPIO_07, IOT_GPIO_PULL_UP);
    if(ret != 0){ 
        printf("IoTGpioSetPull failed :%#x \r\n", ret);
		return;
    }

    /* 设置F3按键为下降沿触发中断 */
    ret = IoTGpioRegisterIsrFunc(KEY3_IO_GPIO_07, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW, Key3Pressed, NULL);
    if(ret != 0){ 
        printf("IoTGpioRegisterIsrFunc failed :%#x \r\n", ret);
		return;
    }

    /* 设置F2按键复用GPIO */
    ret = IoTGpioSetFunc(KEY2_IO_GPIO_02, IOT_GPIO_FUNC_GPIO_2_GPIO);
    if(ret != 0){ 
        printf("IoTGpioInit failed :%#x \r\n", ret);
		return;
    }

    /* 设置F2按键为输入控制 */
    ret = IoTGpioSetDir(KEY2_IO_GPIO_02, IOT_GPIO_DIR_IN);
    if(ret != 0){ 
        printf("IoTGpioSetDir failed :%#x \r\n", ret);
		return;
          }

    /* 设置F2按键为上拉控制 */
    ret = IoTGpioSetPull(KEY2_IO_GPIO_02, IOT_GPIO_PULL_UP);
    if(ret != 0){ 
        printf("IoTGpioSetPull failed :%#x \r\n", ret);
		return;
    }

    /* 设置F2按键为下降沿触发中断 */
    ret = IoTGpioRegisterIsrFunc(KEY2_IO_GPIO_02, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW, Key2Pressed, NULL);
    if(ret != 0){ 
        printf("IoTGpioRegisterIsrFunc failed :%#x \r\n", ret);
		return;
    }
    
    IotUartAttribute uart_attr = {

        //baud_rate: 9600
        .baudRate = 9600,

        //data_bits: 8bits
        .dataBits = 8,
        .stopBits = 1,
        .parity = 0,
    };

    /* 初始化UART */
    ret = IoTUartInit(WIFI_IOT_UART_IDX_1, &uart_attr);
    if (ret != 0)
    {
        printf("IoTUartInit failed :%#x \r\n", ret);
        return;
    }
    printf("UART Test Start\n");
}
static void Key5Pressed(char *arg)
{
    (void)arg;
    IoTUartWrite(WIFI_IOT_UART_IDX_1, (unsigned char *)cmdPlay, 4);
}

static void Key4Pressed(char *arg)
{
    (void)arg;
    IoTUartWrite(WIFI_IOT_UART_IDX_1, (unsigned char *)cmdStop, 4);
}

static void Key3Pressed(char *arg)
{
    (void)arg;
    IoTUartWrite(WIFI_IOT_UART_IDX_1, (unsigned char *)cmdPrev, 4);
}

static void Key2Pressed(char *arg)
{
    (void)arg;
    IoTUartWrite(WIFI_IOT_UART_IDX_1, (unsigned char *)cmdNext, 4);
}
APP_FEATURE_INIT(MusicModuleSample);